/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[AbstractClass.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package objectOriented;

/**
 * 抽象类
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class AbstractClass {

	public static void main(String[] args) {
		Shape triangle1 = new Triangle();
		System.out.println("Grith is " + triangle1.getGirth());
		System.out.println("Area is " + triangle1.getArea());

		// System.out.println((triangle1 instanceof Example_06_Triangle));

		Triangle triangle2 = new Triangle(6, 7, 8);
		System.out.println("Grith is " + triangle2.getGirth());
		System.out.println("Area is " + triangle2.getArea());

		Shape rectangle1 = new Rectangle();
		System.out.println("Grith is " + rectangle1.getGirth());
		System.out.println("Area is " + rectangle1.getArea());

		Rectangle rectangle2 = new Rectangle(10, 20);
		System.out.println("Grith is " + rectangle2.getGirth());
		System.out.println("Area is " + rectangle2.getArea());
	}
}

/**
 * 抽象图形类
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
abstract class Shape {

	// 图形的名称
	protected String name;

	// 获取图形的周长
	public abstract double getGirth();

	// 获取图形的面积
	public abstract double getArea();

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}
}

/**
 * 图形实现类 - 三角形
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
class Triangle extends Shape {

	// 边a的长度
	private double sideA;
	// 边b的长度
	private double sideB;
	// 边c的长度
	private double sideC;

	// 边长错误
	public static final String SIDE_ERROR = "三角形的边长必须大于0";
	// 不能构成三角形的错误
	public static final String SHAPE_ERROR = "三角形的两边之和必须大于第三边";

	public Triangle() {
		this.init();
	}

	private void init() {
		this.sideA = 3;
		this.sideB = 4;
		this.sideC = 5;
	}

	// 用三条边构成一个三角形
	public Triangle(double sideA, double sideB, double sideC) {
		// 如果给定的三边能构成三角形, 那么用给定的变长构成三角形
		if (isTriangle(sideA, sideB, sideC)) {
			this.sideA = sideA;
			this.sideB = sideB;
			this.sideC = sideC;
		} else {
			// 否则, 用默认的变长构成三角形
			this.init();
		}
	}

	// 判断三条边是否能够组成三角形
	private boolean isTriangle(double sideA, double sideB, double sideC) {
		// 边长必须大于0
		if ((sideA <= 0) || (sideB <= 0) || (sideC <= 0)) {
			System.err.println(SIDE_ERROR);
			return false;
		} else if ((sideA + sideB < sideC) || (sideA + sideC) < sideB || (sideB + sideC < sideA)) {// 两边之和必须大于第三边
			System.err.println(SHAPE_ERROR);
			return false;
		}
		return true;
	}

	public double getSideA() {
		return sideA;
	}

	public void setSideA(double sideA) {
		if (this.isTriangle(sideA, this.sideB, this.sideC)) {
			this.sideA = sideA;
		}
	}

	public double getSideB() {
		return sideB;
	}

	public void setSideB(double sideB) {
		if (this.isTriangle(this.sideA, sideB, this.sideC)) {
			this.sideB = sideB;
		}
	}

	public double getSideC() {
		return sideC;
	}

	public void setSideC(double sideC) {
		if (this.isTriangle(this.sideA, this.sideB, sideC)) {
			this.sideC = sideC;
		}
	}

	// 使用海伦公式计算三角形的面积
	@Override
	public double getArea() {
		double s = (this.sideA + this.sideB + this.sideC) / 2;
		return Math.sqrt((s * (s - this.sideA) * (s - this.sideB) * (s - this.sideC)));
	}

	// 计算三角形的周长
	@Override
	public double getGirth() {
		return this.getSideA() + this.getSideB() + this.getSideC();
	}
}

/**
 * 图形实现类 - 矩形
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
class Rectangle extends Shape {

	// 矩形的边长
	private double length;

	// 矩形的边宽
	private double width;

	// 错误提示信息
	public static final String SIDE_ERROR = "矩形的边长必须大于0";

	// 默认构造方法
	public Rectangle() {
		this.init();
	}

	// 初始化矩形的边长
	private void init() {
		this.length = 4;
		this.width = 5;
	}

	public Rectangle(double length, double width) {
		if (length <= 0 || width <= 0) {
			System.err.println(SIDE_ERROR);
			this.init();
		} else {
			this.length = length;
			this.width = width;
		}
	}

	public double getLength() {
		return length;
	}

	public void setLength(double length) {
		if (length > 0) {
			this.length = length;
		} else {
			System.err.println(SIDE_ERROR);
		}
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		if (width > 0) {
			this.width = width;
		} else {
			System.err.println(SIDE_ERROR);
		}
	}

	@Override
	public double getArea() {
		return this.getLength() * this.getWidth();
	}

	@Override
	public double getGirth() {
		return (this.length + this.width) * 2;
	}
}
